//
// RTSPRequest.h
//
// $Id: //base/src/rtsp/RTSPRequest.h
//
// Library: base
// Package: rtsp
// Module : RTSPRequest
// Author :	Jelin,doitsjz@163.com
// Date	  :	10/30/2012
// 
// Definition of the RTSPRequest class.
//
// Copyright (c) 2012-2012, iGuard.
//

#include "RTSPRequest.h"

#include "Poco/Net/NetException.h"
#include "Poco/Net/NameValueCollection.h"
#include "Poco/NumberFormatter.h"
#include "Poco/Ascii.h"


using Poco::NumberFormatter;
using Poco::Net::NotAuthenticatedException;
using Poco::Net::MessageException;
using Poco::Net::NoMessageException;

const std::string RTSPRequest::DESCRIBE      = "DESCRIBE";
const std::string RTSPRequest::SETUP         = "SETUP";
const std::string RTSPRequest::TEARDOWN      = "TEARDOWN";
const std::string RTSPRequest::PLAY          = "PLAY";
const std::string RTSPRequest::PAUSE         = "PAUSE";
const std::string RTSPRequest::OPTIONS       = "OPTIONS";
const std::string RTSPRequest::ANNOUNCE      = "ANNOUNCE";
const std::string RTSPRequest::GET_PARAMETER = "GET_PARAMETER";
const std::string RTSPRequest::SET_PARAMETER = "SET_PARAMETER";
const std::string RTSPRequest::REDIRECT      = "REDIRECT";
const std::string RTSPRequest::RECORD        = "RECORD";
const std::string RTSPRequest::EMPTY;

const std::string RTSPRequest::HOST          = "Host";
const std::string RTSPRequest::COOKIE        = "Cookie";
const std::string RTSPRequest::AUTHORIZATION = "Authorization";


RTSPRequest::RTSPRequest():
	_method(EMPTY),
	_uri("/")
{
}

	
RTSPRequest::RTSPRequest(const std::string& version):
	RTSPMessage(version),
	_method(EMPTY),
	_uri("/")
{
}

	
RTSPRequest::RTSPRequest(const std::string& method, const std::string& uri):
	_method(method),_uri(uri),RTSPMessage(RTSPMessage::RTSP_1_0)
{
}


RTSPRequest::RTSPRequest(const std::string& method, const std::string& uri, const std::string& version):
	RTSPMessage(version),
	_method(method),
	_uri(uri)
{
}


RTSPRequest::~RTSPRequest()
{
}


void RTSPRequest::setMethod(const std::string& method)
{
	_method = method;
}


void RTSPRequest::setURI(const std::string& uri)
{
	_uri = uri;
}

void RTSPRequest::write(std::ostream& ostr) const
{
	ostr << _method << " " << _uri << " " << getVersion() << "\r\n";
	RTSPMessage::write(ostr);
	ostr << "\r\n";
	if (!_body.empty())
		ostr << _body;// << "\r\n";
}


void RTSPRequest::read(std::istream& istr)
{
	static const int eof = std::char_traits<char>::eof();

	std::string method;
	std::string uri;
	std::string version;
	method.reserve(16);
	uri.reserve(64);
	version.reserve(16);
	int ch = istr.get();
	if (ch == eof) throw NoMessageException();
	while (Poco::Ascii::isSpace(ch)) ch = istr.get();
	if (ch == eof) throw MessageException("No HTTP request header");
	while (!Poco::Ascii::isSpace(ch) && ch != eof && method.length() < MAX_METHOD_LENGTH) { method += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP request method invalid or too long");
	while (Poco::Ascii::isSpace(ch)) ch = istr.get();
	while (!Poco::Ascii::isSpace(ch) && ch != eof && uri.length() < MAX_URI_LENGTH) { uri += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP request URI invalid or too long");
	while (Poco::Ascii::isSpace(ch)) ch = istr.get();
	while (!Poco::Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string");
	while (ch != '\n' && ch != eof) { ch = istr.get(); }
	RTSPMessage::read(istr);
	ch = istr.get();
	while (ch != '\n' && ch != eof) { ch = istr.get(); }
	setMethod(method);
	setURI(uri);
	setVersion(version);
}
void RTSPRequest::clear()
{
	_method.clear();
	_uri.clear();
	_body.clear();

	NameValueCollection::clear();
}
